package xyz.xpman.prisonerfitness.kit;

import android.annotation.SuppressLint;
import android.util.Log;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import xyz.xpman.prisonerfitness.entity.Record;

public enum HttpKit {;
    static final String FORM_DATA_TYPE = "multipart/form-data";

    static final String OCTET_TYPE = "application/octet-stream";
    static final String JSON_TYPE = "application/json";
    static final String XML_TYPE = "application/xml";
    // static final String XML_TYPE = "text/xml";

    static final String HTML_TYPE = "text/html";
    static final String TEXT_TYPE = "text/plain";

    static final String DEFAULT_CHARSET = "utf-8";
    static final String DEFAULT_TYPE = JSON_TYPE;
    static final String DEFAULT_MEDIA_TYPE =
            DEFAULT_TYPE + "; charset=" + DEFAULT_CHARSET;

    // 6秒
    static final long timeout = 6000;



    static final OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .callTimeout(timeout, TimeUnit.SECONDS)
            .build();



    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    private static FormBody toFormBody(@NotNull Record parameters) {
        final FormBody.Builder builder = new FormBody.Builder();

        if (!parameters.isEmpty()) {
            final Map<String, String> columns = parameters.toStringMap();

            for (Map.Entry<String, String> entry : columns.entrySet()) {
                builder.add(entry.getKey(), entry.getValue());
            }
        }

        return builder.build();
    }


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



    public static Call get(@NotNull String url,
                           @NotNull Record data) {
        final Request request = new Request.Builder()
                .url(url)
                .get()
                .build();

        return okHttpClient.newCall(request);
    }


    public static Call put(@NotNull String url,
                           @NotNull Record data) {
        final Request request = new Request.Builder()
                .url(url)
                .put(toFormBody(data))
                .build();

        return okHttpClient.newCall(request);
    }




    public static Call post(@NotNull String url,
                            @NotNull Record data) {

        final Request request = new Request.Builder()
                .url(url)
                .post(toFormBody(data))
                .build();

        return okHttpClient.newCall(request);
    }


    public static Call post(@NotNull String url,
                            @NotNull String data,
                            MediaType mediaType) {

        final Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(data, mediaType))
                .build();

        return okHttpClient.newCall(request);
    }


    public static Call post(@NotNull String url,
                            @NotNull String data,
                            String mediaType) {

        return post(url, data, MediaType.parse(mediaType));
    }




    public static Call patch(@NotNull String url,
                             @NotNull Record data) {
        final Request request = new Request.Builder()
                .url(url)
                .patch(toFormBody(data))
                .build();

        return okHttpClient.newCall(request);
    }




    public static Call delete(@NotNull String url,
                              @NotNull Record data) {
        final Request request = new Request.Builder()
                .url(url)
                .delete(toFormBody(data))
                .build();

        return okHttpClient.newCall(request);
    }

    public static Call delete(@NotNull String url) {
        return delete(url, Record.EMPTY);
    }



    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



    public static void testGet() {
        final String url = "http://www.ydczcfmuseum.cn/commonInfo";

        get(url, Record.EMPTY).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Log.e("request", "failure");

            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                Log.i("request", "success: " + Objects.requireNonNull(response.body()).string());

            }
        });
    }

    @SuppressLint("NewApi")
    public static void testPost() {
        final String url = "http://www.ydczcfmuseum.cn/login";
        final String data = "username=root&password=123456";
        final Map<String, Object> map = Map.of(
                "username", "root",
                "password", "123456");
        final Record record = new Record().setColumns(map);

        post(url, data, TEXT_TYPE).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Log.e("request", "failure");

            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                Log.i("request", "success: " + Objects.requireNonNull(response.body()).string());

            }
        });

        post(url, Record.EMPTY).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Log.e("request", "failure");

            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                Log.i("request", "success: " + Objects.requireNonNull(response.body()).string());

            }
        });

        post(url, record).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Log.e("request", "failure");

            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                Log.i("request", "success: " + Objects.requireNonNull(response.body()).string());

            }
        });
    }


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


}
